﻿2026-05-10T11:47:18.8157634Z ##[group]Run pnpm verify:phase-4
2026-05-10T11:47:18.8157975Z [36;1mpnpm verify:phase-4[0m
2026-05-10T11:47:18.8179321Z shell: /usr/bin/bash -e {0}
2026-05-10T11:47:18.8179587Z env:
2026-05-10T11:47:18.8179844Z   PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
2026-05-10T11:47:18.8180171Z   SKIP_PHASE_3_CARRYOVER: 1
2026-05-10T11:47:18.8180579Z   SKIP_TRACE_CHECK: 1
2026-05-10T11:47:18.8180794Z ##[endgroup]
2026-05-10T11:47:19.1233347Z 
2026-05-10T11:47:19.1293097Z > rebno@0.0.0 verify:phase-4 /home/runner/work/rebno/rebno
2026-05-10T11:47:19.1442613Z > node scripts/verify-phase-4.mjs
2026-05-10T11:47:19.1443391Z 
2026-05-10T11:47:19.1596802Z 
2026-05-10T11:47:19.1597111Z === Workspace: typecheck ===
2026-05-10T11:47:19.1597658Z >>> pnpm -r typecheck
2026-05-10T11:47:19.5002168Z Scope: 5 of 6 workspace projects
2026-05-10T11:47:19.5049281Z packages/db typecheck$ tsc --noEmit
2026-05-10T11:47:19.5057701Z packages/game-logic typecheck$ tsc --noEmit
2026-05-10T11:47:22.0593094Z packages/game-logic typecheck: Done
2026-05-10T11:47:22.0608010Z packages/protocol typecheck$ tsc --noEmit
2026-05-10T11:47:24.2779122Z packages/db typecheck: Done
2026-05-10T11:47:25.4997288Z packages/protocol typecheck: Done
2026-05-10T11:47:25.5010101Z apps/client typecheck$ tsc --noEmit
2026-05-10T11:47:25.5013293Z apps/server typecheck$ tsc --noEmit
2026-05-10T11:47:36.3832324Z apps/client typecheck: Done
2026-05-10T11:47:37.4437999Z apps/server typecheck: Done
2026-05-10T11:47:37.4542456Z 
2026-05-10T11:47:37.4563197Z === Lint: protocol-sync ===
2026-05-10T11:47:37.4563781Z >>> pnpm lint:protocol-sync
2026-05-10T11:47:37.7563282Z 
2026-05-10T11:47:37.7564302Z > rebno@0.0.0 lint:protocol-sync /home/runner/work/rebno/rebno
2026-05-10T11:47:37.7565664Z > node tools/scripts/lint-protocol-sync.mjs
2026-05-10T11:47:37.7566389Z 
2026-05-10T11:47:37.7863385Z lint-protocol-sync: OK
2026-05-10T11:47:37.7978349Z 
2026-05-10T11:47:37.7979029Z === Lint: game-logic-purity ===
2026-05-10T11:47:37.7979907Z >>> pnpm lint:game-logic-purity
2026-05-10T11:47:38.0981634Z 
2026-05-10T11:47:38.0982950Z > rebno@0.0.0 lint:game-logic-purity /home/runner/work/rebno/rebno
2026-05-10T11:47:38.0984327Z > node tools/scripts/lint-game-logic-purity.mjs
2026-05-10T11:47:38.0984951Z 
2026-05-10T11:47:38.1281451Z lint-game-logic-purity: OK (6 file(s) clean)
2026-05-10T11:47:38.1394483Z 
2026-05-10T11:47:38.1395107Z === Lint: better-auth-schema-sync ===
2026-05-10T11:47:38.1396166Z >>> pnpm lint:better-auth-schema-sync
2026-05-10T11:47:38.4449810Z 
2026-05-10T11:47:38.4450911Z > rebno@0.0.0 lint:better-auth-schema-sync /home/runner/work/rebno/rebno
2026-05-10T11:47:38.4452520Z > node tools/scripts/lint-better-auth-schema-sync.mjs
2026-05-10T11:47:38.4453295Z 
2026-05-10T11:47:40.0930932Z lint-better-auth-schema-sync: OK
2026-05-10T11:47:40.1051335Z 
2026-05-10T11:47:40.1052306Z === Lint: rate-limit-budgets ===
2026-05-10T11:47:40.1053332Z >>> pnpm lint:rate-limit-budgets
2026-05-10T11:47:40.4067793Z 
2026-05-10T11:47:40.4068850Z > rebno@0.0.0 lint:rate-limit-budgets /home/runner/work/rebno/rebno
2026-05-10T11:47:40.4070257Z > node tools/scripts/lint-rate-limit-budgets.mjs
2026-05-10T11:47:40.4070926Z 
2026-05-10T11:47:40.4369811Z lint-rate-limit-budgets: OK (5 D-22 budgets locked)
2026-05-10T11:47:40.4482437Z 
2026-05-10T11:47:40.4483063Z === Lint: no-clipboard-rce ===
2026-05-10T11:47:40.4483900Z >>> pnpm lint:no-clipboard-rce
2026-05-10T11:47:40.7531274Z 
2026-05-10T11:47:40.7532600Z > rebno@0.0.0 lint:no-clipboard-rce /home/runner/work/rebno/rebno
2026-05-10T11:47:40.7533952Z > node tools/scripts/lint-no-clipboard-rce.mjs
2026-05-10T11:47:40.7534578Z 
2026-05-10T11:47:40.7874840Z lint-no-clipboard-rce: OK (21 file(s) clean)
2026-05-10T11:47:40.7992547Z 
2026-05-10T11:47:40.7993073Z === Lint: room-layout ===
2026-05-10T11:47:40.7993858Z >>> pnpm lint:room-layout
2026-05-10T11:47:41.1026795Z 
2026-05-10T11:47:41.1027825Z > rebno@0.0.0 lint:room-layout /home/runner/work/rebno/rebno
2026-05-10T11:47:41.1029058Z > node tools/scripts/lint-room-layout.mjs
2026-05-10T11:47:41.1030334Z 
2026-05-10T11:47:41.1360698Z lint-room-layout: OK
2026-05-10T11:47:41.1478749Z 
2026-05-10T11:47:41.1479290Z === ADR 0004 lint ===
2026-05-10T11:47:41.1480006Z >>> pnpm lint:adr:0004
2026-05-10T11:47:41.4533714Z 
2026-05-10T11:47:41.4534806Z > rebno@0.0.0 lint:adr:0004 /home/runner/work/rebno/rebno
2026-05-10T11:47:41.4536351Z > node tools/asset-catalog/scripts/lint-adr.mjs docs/adr/0004-room-hot-reload.md --no-matrix
2026-05-10T11:47:41.4537739Z 
2026-05-10T11:47:41.4831299Z OK: ADR docs/adr/0004-room-hot-reload.md validated (no-matrix mode — Michael Nygard sections present)
2026-05-10T11:47:41.4943876Z 
2026-05-10T11:47:41.4944363Z === Drizzle: emit-check ===
2026-05-10T11:47:41.4945260Z >>> pnpm db:emit-check
2026-05-10T11:47:41.8132603Z 
2026-05-10T11:47:41.8133673Z > rebno@0.0.0 db:emit-check /home/runner/work/rebno/rebno
2026-05-10T11:47:41.8136719Z > pnpm -C packages/db exec drizzle-kit generate && node -e "require('fs').copyFileSync('packages/db/migrations/0001_baseline.sql','docs/extracted-server/0001_baseline.sql')" && git diff --exit-code packages/db/migrations/0001_baseline.sql docs/extracted-server/0001_baseline.sql
2026-05-10T11:47:41.8139014Z 
2026-05-10T11:47:42.2589183Z No config path provided, using default 'drizzle.config.ts'
2026-05-10T11:47:42.2591374Z Reading config file '/home/runner/work/rebno/rebno/packages/db/drizzle.config.ts'
2026-05-10T11:47:42.6992308Z 8 tables
2026-05-10T11:47:42.6993269Z accounts 8 columns 1 indexes 0 fks
2026-05-10T11:47:42.6994173Z audit_log 6 columns 0 indexes 2 fks
2026-05-10T11:47:42.6995014Z characters 9 columns 0 indexes 1 fks
2026-05-10T11:47:42.6998284Z inventory_items 4 columns 0 indexes 1 fks
2026-05-10T11:47:42.6999268Z legacy_credentials_staging 6 columns 0 indexes 0 fks
2026-05-10T11:47:42.7000294Z message_board_replies 5 columns 0 indexes 2 fks
2026-05-10T11:47:42.7001259Z message_board_topics 7 columns 0 indexes 1 fks
2026-05-10T11:47:42.7002341Z sessions 5 columns 0 indexes 1 fks
2026-05-10T11:47:42.7002693Z 
2026-05-10T11:47:42.7003286Z No schema changes, nothing to migrate 😴
2026-05-10T11:47:43.0442850Z 
2026-05-10T11:47:43.0454026Z === Drizzle: schema-sync ===
2026-05-10T11:47:43.0454584Z >>> pnpm lint:schema-sync
2026-05-10T11:47:43.3471075Z 
2026-05-10T11:47:43.3472345Z > rebno@0.0.0 lint:schema-sync /home/runner/work/rebno/rebno
2026-05-10T11:47:43.3503258Z > node -e "const a=require('fs').readFileSync('packages/db/migrations/0001_baseline.sql');const b=require('fs').readFileSync('docs/extracted-server/0001_baseline.sql');if(Buffer.compare(a,b)!==0){console.error('docs/extracted-server/0001_baseline.sql out of sync with packages/db/migrations/0001_baseline.sql');process.exit(1)}console.log('OK')"
2026-05-10T11:47:43.3505539Z 
2026-05-10T11:47:43.3745752Z OK
2026-05-10T11:47:43.3871602Z 
2026-05-10T11:47:43.3872438Z === Drizzle: source-comments ===
2026-05-10T11:47:43.3873131Z >>> pnpm lint:source-comments
2026-05-10T11:47:43.7047714Z 
2026-05-10T11:47:43.7048851Z > rebno@0.0.0 lint:source-comments /home/runner/work/rebno/rebno
2026-05-10T11:47:43.7050712Z > pnpm -C packages/db run lint:source-comments
2026-05-10T11:47:43.7051449Z 
2026-05-10T11:47:44.0109458Z 
2026-05-10T11:47:44.0110693Z > @rebno/db@0.1.0 lint:source-comments /home/runner/work/rebno/rebno/packages/db
2026-05-10T11:47:44.0112682Z > node scripts/check-source-comments.mjs
2026-05-10T11:47:44.0113351Z 
2026-05-10T11:47:44.0416252Z check-source-comments: OK (50 columns, all SOURCE-cited)
2026-05-10T11:47:44.0619400Z 
2026-05-10T11:47:44.0619911Z === Workspace: test ===
2026-05-10T11:47:44.0621085Z >>> pnpm -r test
2026-05-10T11:47:44.3909825Z Scope: 5 of 6 workspace projects
2026-05-10T11:47:44.3965299Z packages/db test$ vitest run
2026-05-10T11:47:44.3974185Z packages/game-logic test$ vitest run
2026-05-10T11:47:44.9166725Z packages/db test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/db[39m
2026-05-10T11:47:44.9169116Z packages/game-logic test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/game-logic[39m
2026-05-10T11:47:45.3087880Z packages/game-logic test:  [32m✓[39m test/golden.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-10T11:47:45.5093571Z packages/game-logic test:  [32m✓[39m test/platform-cycle.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 19[2mms[22m[39m
2026-05-10T11:47:45.7391322Z packages/game-logic test:  [32m✓[39m test/accumulator.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-10T11:47:45.9559718Z packages/db test:  [32m✓[39m tests/promotion.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-10T11:47:45.9829562Z packages/game-logic test:  [32m✓[39m test/rng.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-10T11:47:45.9831597Z packages/game-logic test: [2m Test Files [22m [1m[32m4 passed[39m[22m[90m (4)[39m
2026-05-10T11:47:45.9834030Z packages/game-logic test: [2m      Tests [22m [1m[32m21 passed[39m[22m[90m (21)[39m
2026-05-10T11:47:45.9835649Z packages/game-logic test: [2m   Start at [22m 11:47:44
2026-05-10T11:47:45.9837815Z packages/game-logic test: [2m   Duration [22m 1.06s[2m (transform 132ms, setup 0ms, import 221ms, tests 52ms, environment 1ms)[22m
2026-05-10T11:47:46.0186302Z packages/game-logic test: Done
2026-05-10T11:47:46.0202942Z packages/protocol test$ vitest run
2026-05-10T11:47:46.1874181Z packages/db test:  [32m✓[39m tests/save-format-traceability.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-10T11:47:46.5238282Z packages/protocol test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/protocol[39m
2026-05-10T11:47:46.9179895Z packages/protocol test:  [32m✓[39m test/codec.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 22[2mms[22m[39m
2026-05-10T11:47:47.0675565Z packages/db test:  [32m✓[39m tests/schema-shape.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 14[2mms[22m[39m
2026-05-10T11:47:47.0717359Z packages/db test: [2m Test Files [22m [1m[32m3 passed[39m[22m[90m (3)[39m
2026-05-10T11:47:47.0733029Z packages/db test: [2m      Tests [22m [1m[32m22 passed[39m[22m[90m (22)[39m
2026-05-10T11:47:47.0756960Z packages/db test: [2m   Start at [22m 11:47:44
2026-05-10T11:47:47.0773397Z packages/db test: [2m   Duration [22m 2.16s[2m (transform 181ms, setup 0ms, import 1.52s, tests 31ms, environment 1ms)[22m
2026-05-10T11:47:47.1066716Z packages/db test: Done
2026-05-10T11:47:47.1464512Z packages/protocol test:  [32m✓[39m test/intents.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-10T11:47:47.3137350Z packages/protocol test:  [32m✓[39m test/schema-shape.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-10T11:47:47.4672097Z packages/protocol test:  [32m✓[39m test/state.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-10T11:47:47.4743587Z packages/protocol test: [2m Test Files [22m [1m[32m4 passed[39m[22m[90m (4)[39m
2026-05-10T11:47:47.4753163Z packages/protocol test: [2m      Tests [22m [1m[32m30 passed[39m[22m[90m (30)[39m
2026-05-10T11:47:47.4769805Z packages/protocol test: [2m   Start at [22m 11:47:46
2026-05-10T11:47:47.4775330Z packages/protocol test: [2m   Duration [22m 940ms[2m (transform 116ms, setup 0ms, import 240ms, tests 38ms, environment 1ms)[22m
2026-05-10T11:47:47.5092987Z packages/protocol test: Done
2026-05-10T11:47:47.5113884Z apps/client test$ vitest run --exclude 'test/e2e/**'
2026-05-10T11:47:47.5114811Z apps/server test$ vitest run --exclude 'test/**/*.integ.test.ts'
2026-05-10T11:47:48.0683995Z apps/server test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/apps/server[39m
2026-05-10T11:47:48.1104621Z apps/client test: [1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/runner/work/rebno/rebno/apps/client[39m
2026-05-10T11:47:49.2374404Z apps/server test:  [32m✓[39m test/persistence.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 60[2mms[22m[39m
2026-05-10T11:47:49.5862858Z apps/server test:  [32m✓[39m test/rate-limit.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-10T11:47:49.6989904Z apps/client test: [90mstderr[2m | src/__test__/game-scene.test.ts[2m > [22m[2mscenes/GameScene[2m > [22m[2mtest 5: onRoomLayout calls verifyRoomLayout first; render skipped on false
2026-05-10T11:47:49.7007029Z apps/client test: [22m[39mroom_layout signature did not verify — rendering skipped for mvp-lobby 000
2026-05-10T11:47:49.7146457Z apps/client test:  [32m✓[39m src/__test__/game-scene.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 155[2mms[22m[39m
2026-05-10T11:47:49.8774045Z apps/server test:  [32m✓[39m test/room-key.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 23[2mms[22m[39m
2026-05-10T11:47:50.1874256Z apps/server test: {"level":40,"time":1778413670181,"pid":3219,"hostname":"runnervmeorf1","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-10T11:47:50.1921673Z apps/server test:  [32m✓[39m test/staging-invite.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 13[2mms[22m[39m
2026-05-10T11:47:50.1943288Z apps/server test: {"level":40,"time":1778413670185,"pid":3219,"hostname":"runnervmeorf1","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-10T11:47:50.1959984Z apps/server test: {"level":40,"time":1778413670186,"pid":3219,"hostname":"runnervmeorf1","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-10T11:47:50.8969593Z apps/client test:  [32m✓[39m src/__test__/login-scene.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-10T11:47:51.0623860Z apps/server test: {"level":30,"time":1778413671059,"pid":3239,"hostname":"runnervmeorf1","password":"[Redacted]","session_token":"[Redacted]","msg":"login"}
2026-05-10T11:47:51.0699697Z apps/server test:  [32m✓[39m test/otel-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[33m 652[2mms[22m[39m
2026-05-10T11:47:51.0737791Z apps/server test:      [33m[2m✓[22m[39m does not throw when OTEL_EXPORTER_OTLP_ENDPOINT is unset [33m 552[2mms[22m[39m
2026-05-10T11:47:51.9843528Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 1: fresh DB — migrate creates accounts table and records migration row
2026-05-10T11:47:51.9873797Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-OjOYhr/rebno.db
2026-05-10T11:47:51.9875819Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-10T11:47:51.9877228Z apps/server test: [run-migrations] OK
2026-05-10T11:47:52.0054408Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 2: pre-bootstrapped DB (Assumption A7) — reconcile seeds row before migrate runs
2026-05-10T11:47:52.0105515Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-hCuIRW/rebno.db
2026-05-10T11:47:52.0138103Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-10T11:47:52.0164042Z apps/server test: [run-migrations] reconciled __drizzle_migrations for pre-bootstrap DB (Assumption A7) — seeded 0001_baseline
2026-05-10T11:47:52.0182852Z apps/server test: [run-migrations] OK
2026-05-10T11:47:52.0224262Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-10T11:47:52.0226663Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-53zKlz/rebno.db
2026-05-10T11:47:52.0243859Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-10T11:47:52.0245262Z apps/server test: [run-migrations] OK
2026-05-10T11:47:52.0258651Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-10T11:47:52.0261591Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-53zKlz/rebno.db
2026-05-10T11:47:52.0263581Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-10T11:47:52.0264872Z apps/server test: [run-migrations] OK
2026-05-10T11:47:52.0368469Z apps/server test:  [32m✓[39m test/run-migrations.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 70[2mms[22m[39m
2026-05-10T11:47:52.2176882Z apps/client test:  [32m✓[39m src/__test__/colyseus-client.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-10T11:47:52.3254257Z apps/server test:  [32m✓[39m test/log.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 22[2mms[22m[39m
2026-05-10T11:47:52.5920729Z apps/server test:  [32m✓[39m test/admin-stubs.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 17[2mms[22m[39m
2026-05-10T11:47:52.9138743Z apps/server test:  [32m✓[39m test/legacy-login.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 27[2mms[22m[39m
2026-05-10T11:47:53.1578288Z apps/server test:  [32m✓[39m test/health.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-10T11:47:53.3958292Z apps/client test:  [32m✓[39m src/__test__/reconnect.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 112[2mms[22m[39m
2026-05-10T11:47:54.0010125Z apps/server test: [90mstdout[2m | test/tick-accumulator.test.ts
2026-05-10T11:47:54.0013499Z apps/server test: [22m[39m◇ injected env (50) from ../../../../../../../etc/environment // tip: ⌘ enable debugging { debug: true }
2026-05-10T11:47:54.0017864Z apps/server test: ℹ️  optional .env file not found: .env.test, .env
2026-05-10T11:47:54.6686421Z apps/client test:  [32m✓[39m src/__test__/chat-hud.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 128[2mms[22m[39m
2026-05-10T11:47:54.7297937Z apps/server test:  [32m✓[39m test/tick-accumulator.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-10T11:47:54.7373181Z apps/server test: [2m Test Files [22m [1m[32m11 passed[39m[22m[90m (11)[39m
2026-05-10T11:47:54.7378303Z apps/server test: [2m      Tests [22m [1m[32m61 passed[39m[22m[90m (61)[39m
2026-05-10T11:47:54.7393963Z apps/server test: [2m   Start at [22m 11:47:48
2026-05-10T11:47:54.7406095Z apps/server test: [2m   Duration [22m 6.66s[2m (transform 422ms, setup 0ms, import 3.37s, tests 909ms, environment 2ms)[22m
2026-05-10T11:47:54.7760089Z apps/server test: Done
2026-05-10T11:47:55.3830564Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-10T11:47:56.1472891Z apps/client test:  [32m✓[39m src/__test__/force-reset-overlay.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 73[2mms[22m[39m
2026-05-10T11:47:56.8358436Z apps/client test:  [32m✓[39m src/__test__/prediction.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-10T11:47:57.5121604Z apps/client test:  [32m✓[39m src/__test__/extrapolation.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-10T11:47:58.1829147Z apps/client test:  [32m✓[39m src/__test__/reconciler.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-10T11:47:58.8601075Z apps/client test:  [32m✓[39m src/__test__/nameplate.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 25[2mms[22m[39m
2026-05-10T11:47:59.5409008Z apps/client test:  [32m✓[39m src/__test__/room-layout-verify.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-10T11:48:00.2182223Z apps/client test:  [32m✓[39m src/__test__/auth-client.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-10T11:48:00.8909550Z apps/client test:  [32m✓[39m src/__test__/atlas-loader.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-10T11:48:01.5397397Z apps/client test:  [32m✓[39m src/__test__/protocol-version-check.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-10T11:48:02.2025606Z apps/client test:  [32m✓[39m src/__test__/env.test.ts [2m([22m[2m5 tests[22m[2m | [22m[33m4 skipped[39m[2m)[22m[32m 4[2mms[22m[39m
2026-05-10T11:48:02.2239248Z apps/client test: [2m Test Files [22m [1m[32m16 passed[39m[22m[90m (16)[39m
2026-05-10T11:48:02.2241117Z apps/client test: [2m      Tests [22m [1m[32m98 passed[39m[22m[2m | [22m[90m4 todo[39m[90m (102)[39m
2026-05-10T11:48:02.2257087Z apps/client test: [2m   Start at [22m 11:47:48
2026-05-10T11:48:02.2258926Z apps/client test: [2m   Duration [22m 14.11s[2m (transform 541ms, setup 48ms, collect 879ms, tests 589ms, environment 8.19s, prepare 1.58s)[22m
2026-05-10T11:48:02.3590823Z apps/client test: Done
2026-05-10T11:48:02.3669391Z 
2026-05-10T11:48:02.3670626Z verify-phase-4: OK (12 steps green)
